package se.energimyndigheten.lampguiden.bulbreplacement;

import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import org.json.JSONException;

import java.io.IOException;
import java.util.Map;

import se.energimyndigheten.lampguiden.HasInfoPage;
import se.energimyndigheten.lampguiden.HasParallaxView;
import se.energimyndigheten.lampguiden.LightSource;
import se.energimyndigheten.lampguiden.MainActivity;
import se.energimyndigheten.lampguiden.R;
import se.energimyndigheten.lampguiden.SwappableFragment;
import se.energimyndigheten.lampguiden.XmlClickable;
import se.energimyndigheten.lampguiden.bulbreplacement.SetPriceDialogFragment.PriceCalculator;
import se.energimyndigheten.lampguiden.util.AssetsUtil;

public class ResultFragment extends SwappableFragment implements XmlClickable, PriceCalculator, HasParallaxView, HasInfoPage {

    private static final String TAG = ResultFragment.class.getSimpleName();
    private static final String EXPLAIN_PATH = MainActivity.HTML_BASEPATH + "sv_Sa_har_vi_raknat.html";
    private static final String INFO_PATH = "Help/sv_ResultList.html";
    private static final String DIALOG_TAG = "price_dialog";

    private LightSource mLight;
    private int mPower;
    private int mSocket;
    private SetPriceDialogFragment mDialog;
    private ResultCardFragment mFrag;
    private Map<Integer, String> mConversionTable;
    private ComparisonCalculator mCalculator;
    private String mLumen = "";
    private View mView;
    private int mMaxHeight = 0;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Log.v(TAG, "onCreateView");
        setRetainInstance(true);
        setHasOptionsMenu(true);
        return inflater.inflate(R.layout.result_activity, container, false);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        //Log.v(TAG, "onViewCreated");
        final FragmentActivity parent = getActivity();

        Bundle args = getArguments();
        mSocket = args.getInt(SocketGridFragment.KEY_SOCKET, -1);
        mPower = args.getInt(PowerFragment.KEY_POWER, -1);

        prepareCalculations();
        // update title label
        ((TextView) parent.findViewById(android.R.id.text2)).setText(getResources().getString(R.string.power_lumen_label, mLumen));
        mView = view.findViewById(R.id.parallax);

        // show frag
        FragmentManager fragmentManager = parent.getSupportFragmentManager();
        FragmentTransaction ft = fragmentManager.beginTransaction();
        mFrag = ResultCardFragment.newInstance(this, mCalculator);
        ft.add(R.id.fragment_container, mFrag, TAG);
        ft.setTransition(FragmentTransaction.TRANSIT_NONE);
        ft.commit();

        setTitle(R.string.title_results);
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        // Log.v(TAG, "onConfigurationChange");
        LayoutInflater inflater = LayoutInflater.from(getActivity());
        initView(inflater, (ViewGroup) getView());
        ((TextView) getView().findViewById(android.R.id.text2)).setText(getResources().getString(R.string.power_lumen_label, mLumen));
    }

    private void initView(LayoutInflater inflater, ViewGroup view) {
        //Log.v(TAG, "initView");
        view.removeAllViews();
        inflater.inflate(R.layout.result_activity, view);
        mView = view.findViewById(R.id.parallax);
        mMaxHeight = mView.getHeight();

        // show frag
        mFrag = ResultCardFragment.newInstance(this, mCalculator);
        FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
        ft.replace(R.id.fragment_container, mFrag);
        ft.setTransition(FragmentTransaction.TRANSIT_NONE);
        ft.commit();
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        menu.clear();
        inflater.inflate(R.menu.actionbar_info, menu);
        super.onCreateOptionsMenu(menu, inflater);
    }

    private void prepareCalculations() {
        //Log.v(TAG, "prepareCalculations");
        try {
            String json = AssetsUtil.getFileContents(getActivity().getAssets(), AssetsUtil.JSON_PATH_LIGHTSOURCE);
            mLight = AssetsUtil.getLightSourceFromJson(json, mSocket);
            mConversionTable = AssetsUtil.getConversionTableFromJson(json, mLight.getLampType());
            mLumen = mConversionTable.get(mPower);
            String[] split = mLumen.split(",");
            if (split[0].equals(split[1])) {
                mLumen = split[0];
            } else {
                mLumen = mLumen.replace(",", " - ");
            }
        } catch (NullPointerException npE) {
            npE.printStackTrace();
        } catch (JSONException jsonE) {
            Log.e(TAG, "JSONException parsing JSON to LightSource");
            jsonE.printStackTrace();
            mSocket = -1;
        } catch (IOException ioE) {
            Log.e(TAG, "IOException reading JSON");
            ioE.printStackTrace();
            mSocket = -1;
        }
        if (mSocket == -1 && mPower == -1) {
            // fail - bail
            Log.e(TAG, "Could not prepare calculations");
            return;
        }

        // initiate comparison calculator
        mCalculator = null;
        try {
            mCalculator = ComparisonCalculator.initiateCalculator(getActivity(), mLight, mPower, mConversionTable);
        } catch (JSONException e) {
            Log.e(TAG, "JSONException reading calculation data.");
            e.printStackTrace();
        } catch (IOException e) {
            Log.e(TAG, "IOException reading calculation file.");
            e.printStackTrace();
        }
        if (mCalculator == null) {
            Log.e(TAG, "Could not initialize ComparisonCalculator");
        }
    }

    private void showEditDialog() {
        FragmentManager fm = getActivity().getSupportFragmentManager();
        mDialog = SetPriceDialogFragment.newInstance(this, mLight);
        mDialog.show(fm, DIALOG_TAG);
    }

    @Override
    public void onXmlClick(View view) {
        final int id = view.getId();
        switch (id) {
            case R.id.result_card_btn_change_price:
                mLight = (LightSource) view.getTag();
                showEditDialog();
                break;
            case R.id.result_card_btn_calculation:
                ExplainFragment eFrag = new ExplainFragment();
                Bundle args = new Bundle();
                args.putString(ExplainFragment.EXTRA_HTML_PATH, EXPLAIN_PATH);
                eFrag.setArguments(args);
                swapFragment(eFrag, true);
                ((ActionBarActivity) getActivity()).getSupportActionBar().setTitle(R.string.result_savings_formula_label);
                break;
            case R.id.result_card_btn_info:
                handleItemSelection((View) view.getParent());
                break;
            case R.id.change_price_dialog_btn_ok:
            case R.id.change_price_dialog_btn_reset:
                mDialog.onXmlClick(view);
                break;
        }
    }

    public void handleItemSelection(View v) {
        LightSource light = (LightSource) v.findViewById(R.id.result_card_btn_change_price).getTag();
        // final String document = light.getDocument();
        final String html_path = MainActivity.HTML_BASEPATH + "Lamptyper/sv_" + light.getDocument() + ".html";
        ExplainFragment eFrag = new ExplainFragment();
        Bundle args = new Bundle();
        args.putString(ExplainFragment.EXTRA_HTML_PATH, html_path);
        eFrag.setArguments(args);

        swapFragment(eFrag, true);
    }

    @Override
    public void onPriceChanged(int price) {
        // FIXME: handle price == -1
        mDialog.dismiss();
        if (mLight != null) {
            mLight.setPrice(price);
            mCalculator.savePrice(price, mLight);
        }
        if (mFrag != null) {
            mFrag.onDataChanged();
        }
    }

    @Override
    public int calculateSavings(int price) {
        //Log.v(TAG, "calculateSavings: " + price);
        if (mLight == null)
            return 0;
        return mCalculator.getCostComparison(mLight, price);
    }

    public View getParallaxView() {
        return mView;
    }

    /**
     * Child scrollable call this. Update the parallax container according to offset
     * @param offset incoming parameter for relative scrolling.
     * @return the new height of the parallax view
     */
    public int doParallaxScroll(int offset) {
        //Log.v(TAG, "doParallaxScroll");
        if (mMaxHeight == 0) {
            mMaxHeight = mView.getHeight();
        }
        int height = mView.getHeight();
        int headerHeight = height - (offset / 2);
        headerHeight = headerHeight < 0 ? 0 : headerHeight;
        headerHeight = headerHeight > mMaxHeight ? mMaxHeight : headerHeight;
        ViewGroup.LayoutParams params = mView.getLayoutParams();
        params.height = headerHeight;
        mView.setLayoutParams(params);
        return headerHeight;
    }

    @Override
    public String getInfoPageUrl() {
        return INFO_PATH;
    }

    @Override
    public String getInfoPageTitle() {
        return getResources().getString(R.string.section_socket_title);
    }
}
